;; 'main' program for testing P System
;;
;; Copyright 2011:
;; James McDermott <jamesmichaelmcdermott@gmail.com>
;; Mark Wagy <mark.wagy@gmail.com>
;;
;; This file is part of p-gen, a p-systems and evolutionary system
;; written in Clojure.
;;
;; p-gen is licensed under GNU GPL v3.
;;
;; http://code.google.com/p/p-gen/

(ns psystem.main (:use psystem.psys) (:require psystem.cli) (:require clojure.string))

;; test objects
(def o1 (make-obj ['A 'B 'A 'B]))
(def o2 (make-obj ['B 'B]))
(def o3 (make-obj ['c 'B 'Z]))
(def o4 (make-obj ['x 'y]))
(def o5 (make-obj ['A 'b 'c 'B]))
(def o6 (make-obj ['c 'B'z]))

;;(println "Adding objects: ")
;;(println (psystem.psys/obj-tostring o1))
;;(println (psystem.psys/obj-tostring o2))
;;(println (psystem.psys/obj-tostring o3))
;;(println (psystem.psys/obj-tostring o4))
;;(println (psystem.psys/obj-tostring o5))
;;(println (psystem.psys/obj-tostring o6))

;; test rules
(def r1 (make-rule [o1] [o4]))
(def r2 (make-rule-withmove [o2] [o5 o1 o2] 2))
(def r3 (make-rule [o1 o2] [o6]))

;;(println "Adding rules: ")
;;(println (psystem.psys/rule-tostring r1))
;;(println (psystem.psys/rule-tostring r2))
;;(println (psystem.psys/rule-tostring r3))

;; test objz
(def oz1 [o1 o2 o3])
(def oz2 [o2 o3])
(def oz3 [o1])

;;(println "Object sequence oz1: ")
;;(println (map psystem.psys/obj-tostring oz1))
;;(println "Object sequence oz2: ")
;;(println (map psystem.psys/obj-tostring oz2))
;;(println "Object sequence oz3: ")
;;(println (map psystem.psys/obj-tostring oz3))

;; rule sequence
(def rz1 [r1 r2])
(def rz2 [r2 r3])

;;(println "rule sequence rz1: ")
;;(print (map psystem.psys/rule-tostring rz1))
;;(println "rule sequence rz2: ")
;;(print (map psystem.psys/rule-tostring rz1))

;; test membranes
(def m1 (psystem.psys/make-membrane 1 rz1))
(def m2 (psystem.psys/make-membrane 2 rz2 (objz-from-rulz rz2) [m1]))

;;(println "Adding membrane m1: ")
;;(println (psystem.psys/membrane-tostring m1))
;;(println "Adding membrane m2: ")
;;(println (psystem.psys/membrane-tostring m2))

;; test psystems
(def p1 (psystem.psys/make-psystem [m1 m2] (:id m2)))

;;(println "Adding P-system p1: ")
;;(println (psystem.psys/psystem-tostring p1))

;; rewrite tests
;;(println "---------- Rewrites ----------")
;;(println "rewrite objects: ")
;;(println (map obj-tostring oz2))
;;(println "rewrite rules: ")
;;(println (clojure.string/join "\n" (map rule-tostring rz1)))
;;(println "rewrite: ")
;;;;(println (map obj-tostring (rewrite-rulz rz1 oz2)))

;; enumerations

;;(println "---------- Membrane Enumeration ----------")
;;(println "membrane (m1) :")
;;(println (membrane-tostring m1))
;;(println "enumeration (1 time): ")
;;(println (membrane-tostring (enumerate-membrane m1)))
;;(println "enumeration (3 times): ")
;;(println (membrane-tostring (enumerate-membrane m1)))
;;(println "enumeration (5 times): ")
;;(println (membrane-tostring (enumerate-membrane m1)))

;;(println "---------- P-system Enumeration ----------")
;;(println "p system (p1) : ")
;;(println (psystem-tostring p1))
;;(println "enumeration (1 time): ")
;;(println (psystem-tostring (enumerate-psystem p1 1)))
;;(println "enumeration (3 time): ")
;;(println (psystem-tostring (enumerate-psystem p1 3)))
;;(println "enumeration (5 time): ")
;;(println (psystem-tostring (enumerate-psystem p1 5)))

;; ;;(println "---------- Conversion to vector ----------")
;; ;;(println "object:")
;; ;;(println (obj-tovec o1))
;; ;;(println "objects:")
;; ;;(println (objz-tovec oz1))
;; ;;(println "rule:")
;; ;;(println (rul-tovec r1))
;; ;;(println "rules:")
;; ;;(println (rulz-tovec rz1))
;; ;;(println "membrane:")
;; ;;(println (membrane-tovec m1))
;; ;;(println "p system: ")
;; ;;(println (psystem-tovec p1))

;; ;;(println "---------- Conversion to XML ----------")
;; ;;(println "object:")
;; ;;(println (obj-toxml o1))
;; ;;(println "objects:")
;; ;;(println (objz-toxml oz1))
;; ;;(println "rule:")
;; ;;(println (rul-toxml r1))
;; ;;(println "rules:")
;; ;;(println (rulz-toxml rz1))
;; ;;(println "membrane:")
;; ;;(println (membrane-toxml m1))
;; ;;(println "p system: ")
;; ;;(println (psystem-toxml p1))



;; psystem to test inter-membrane moves
(println "---------- TEST INTER-MEMBRANE MOVEMENT ----------")

;; objects
(def oa (make-obj ['a]))
(def ob (make-obj ['b]))
(def oc (make-obj ['c]))
(def od (make-obj ['d]))

;; rules
(def rab (make-rule-withmove [oa] [ob] 1))
(def rcd (make-rule-withmove [oc] [od] 1))
(def rba (make-rule-withmove [ob] [oa] 2))

(def m2 (make-membrane 2 [rab rcd] [oa oc]))
(def m1 (make-membrane 1 [rba] [] [m2]))

(def psys-move (make-psystem [m1] [(:id m1)]))

(println "Original P-system: ")
(println (psystem.psys/psystem-tostring psys-move))

(println "enumeration (1 time): ")
(println (psystem-tostring (enumerate-psystem psys-move 1)))

(println "enumeration (2 times): ")
(println (psystem-tostring (enumerate-psystem psys-move 2)))

(println "enumeration (3 times): ")
(println (psystem-tostring (enumerate-psystem psys-move 3)))
